#ifndef SERVERMAINTHREAD_H
#define SERVERMAINTHREAD_H

class ServerWorld;
class Loader;
#include "MainHeader.h"

#include "CommunicationProtocol.h"

#ifdef SERVER

class ServerClientThread {
private:
	bool				m_Terminate;
	bool				m_init;
	SOCKET				m_Socket;
	int					m_ID;

	Loader*				m_pLoader;
	ServerWorld*		m_pWorld;
	ServerMainThread*	m_pGlobalCon;
protected:
	static DWORD WINAPI run( LPVOID pParam );

	void	Dispatch(BYTE * memory, int size);
public:
	HANDLE				m_Thread_Handle;

	ServerClientThread( ServerWorld* pWorld, ServerMainThread* pCon, SOCKET socket);
	~ServerClientThread();

	void Terminate();

	int		Send(BYTE * memory, int size);
	int		Send(Protostruct proto, BYTE * memory, int size);
	int		Send(Protostruct proto, pair<BYTE*,int> * memory, int count);

	int		SendExcept(BYTE * memory, int size);
	int		SendExcept(Protostruct proto, BYTE * memory, int size);
	int		SendExcept(Protostruct proto, pair<BYTE*,int> * memory, int count);

	void init(int ID);
};

class ServerMainThread {
private:
	bool								m_Terminate;
	int									m_CurID;
	SRWLOCK								m_LOCK;
	std::map<int, ServerClientThread*>	m_Clients;


	ServerWorld*						m_pWorld;
protected:
	static DWORD WINAPI run( LPVOID pParam );
public:
	HANDLE				m_Thread_Handle;

	ServerMainThread( ServerWorld* pWorld);

	void Terminate() {
		m_Terminate		= true;
		WaitForSingleObject(m_Thread_Handle, 1000);
	};


	int		Send(int ID, BYTE * memory, int size);
	int		Send(int ID, Protostruct proto, BYTE * memory, int size);
	int		Send(int ID, Protostruct proto, pair<BYTE*,int> * memory, int count);

	int		SendExcept(int ID, BYTE * memory, int size);
	int		SendExcept(int ID, Protostruct proto, BYTE * memory, int size);
	int		SendExcept(int ID, Protostruct proto, pair<BYTE*,int> * memory, int count);

	int		SendAll(BYTE * memory, int size);
	int		SendAll(Protostruct proto, BYTE * memory, int size);
	int		SendAll(Protostruct proto, pair<BYTE*,int> * memory, int count);

	int		Insert(ServerClientThread * client);
	void	Remove(int id);
};
#endif /* SERVER */

#endif /* SERVERMAINTHREAD_H */